package org.parademo.web.controller;

import org.parademo.model.CountryEntity;
import org.parademo.model.UserEntity;
import org.parademo.service.CountryService;
import org.parademo.service.UserService;
import org.parademo.service.security.SecurityUtil;
import org.parademo.web.model.UserProfileView;
import org.parademo.web.model.UserView;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Controller
public class UserController {

    private final UserService userService;
    private final CountryService countryService;
    private final CustomDateEditor customDateEditor;

    public UserController(UserService userService, CountryService countryService, CustomDateEditor dateEditor) {
        this.userService = userService;
        this.countryService = countryService;
        this.customDateEditor = dateEditor;
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, customDateEditor);
    }

    /**
     * Get the current user's profile to view/edit.
     * @param model
     * @return
     */
    @RequestMapping(value = "/profile", method = RequestMethod.GET)
    public String getCurrentUserProfile(Model model) {

        String userName = SecurityUtil.getCurrentUserName();
        getUser(model, userName);
        return "profile";
    }

    /**
     * Get the current user's profile to view/edit.
     * @param model
     * @return
     */
    @RequestMapping(value = "/profile", method = RequestMethod.POST)
    public String updateCurrentUserProfile(@ModelAttribute("userProfile") UserProfileView user,
                                           BindingResult bindingResult,
                                           Model model) {
        user.validateUsing(bindingResult);

        if (bindingResult.hasErrors()) {
            return "profile";
        }

        userService.update(user);

        return "redirect:/home";
    }

    /**
     * Get any user's profile.
     * @param model
     * @param userName
     * @return
     */
    @RequestMapping(value="/users/{userName}", method= RequestMethod.GET)
    public String getUser(Model model, @PathVariable("userName") String userName) {

        UserEntity userProfile = userService.getUserByUserName(userName);
        List<CountryEntity> countries =  countryService.getCountries();
        
        model.addAttribute("userProfile", new UserProfileView(userProfile) );
        model.addAttribute("countries", countries );

        return "users";
    }

    @RequestMapping(value="/users", method= RequestMethod.GET)
    public String getUserList(Model model) {
        List<UserEntity> users = userService.getUsers();

        model.addAttribute("users", getViewUsers(users));

        return "users";
    }

    private List<UserView> getViewUsers(List<UserEntity> users) {
        List<UserView> result = new ArrayList<UserView>();

        for (UserEntity user : users) {
            result.add(
                    new UserView(user)
            );
        }

        return result;
    }

}
